import os

from django.conf import settings
from django.shortcuts import render
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from alipay import AliPay
from orders.models import OrderInfo

# GET /orders/(?P<order_id>\d+)/payment/
from payment.models import Payment


class PaymentView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, order_id):
        """
        获取支付宝支付网址:
        1. 根据`order_id`获取订单信息并校验是否有效
        2. 组织支付宝支付网址和参数
        3. 返回支付宝支付网址
        """
        # 获取登录用户
        user = request.user

        # 1. 根据`order_id`获取订单信息并校验是否有效
        try:
            order = OrderInfo.objects.get(
                order_id=order_id,
                user=user,
                pay_method=OrderInfo.PAY_METHODS_ENUM['ALIPAY'],
                status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']
            )
        except OrderInfo.DoesNotExist:
            return Response({'message': '无效的订单id'}, status=status.HTTP_400_BAD_REQUEST)

        # 2. 组织支付宝支付网址和参数
        # 初始化
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,  # 应用APPID
            app_notify_url=None,  # 默认回调url
            app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem"),
            # 网站私钥文件路径
            alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                "keys/alipay_public_key.pem"),  # 支付宝公钥文件路径
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 是否使用沙箱环境
        )

        # 组织支付参数
        # 电脑网站支付，需要跳转到https://openapi.alipaydev.com/gateway.do? + order_string
        total_pay = order.total_amount  # Decimal

        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,  # 订单编号
            total_amount=str(total_pay),  # 实付款
            subject='美多商城%s' % order_id,  # 订单标题
            return_url="http://www.meiduo.site:8080/pay_success.html"  # 回调地址
        )

        # 3. 返回支付宝支付网址
        alipay_url = settings.ALIPAY_URL + '?' + order_string
        return Response({'alipay_url': alipay_url})


# Create your views here.

# charset=utf-8&
# out_trade_no=201812230952420000000002& # 商户订单号
# method=alipay.trade.page.pay.return&
# total_amount=3398.00&
# 签名字符串
# sign=evGROwc5NNnQaXMlm1ud9HYs8yW8UqhakQCpi6yiH%2FKZiRWS7Vz%2BvlTVpBuz8FNsoX5TH8Tdv%2F%2FM%2BaKNiFqWUX%2B4YgYJ4Akah6CWq85vQ3CSRr7ZNqVF9bTmp9dcaQggrTuxKBc%2BV8PCjo59UW9ZU8W5M2kJadZ97aMorMYi2DnxtCz4slHO0C%2FgfbP7nYnctHk8EV%2FlYNybca6ai%2BynRCSp361Fn%2BYKrspZ4bpMzr9%2BHHLnVW4EOjUSUD9Dr%2FEhw3QNa%2BR8Y%2FDTpQ9BggGpr%2FKHJipzhk%2FVTXEtq30LgJc84c0%2BNlMsBiQeLvVgIxvzQoC96tU07OdO4zf8CwVwOw%3D%3D&
# trade_no=2018122322001485920500673104& # 支付交易号
# auth_app_id=2016090800464054&
# version=1.0&
# app_id=2016090800464054&
# sign_type=RSA2&
# seller_id=2088102174694091&
# timestamp=2018-12-23+09%3A56%3A19


# PUT /payment/status/?支付结果参数
class PaymentStatusView(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request):
        """
        保存支付结果信息:
        1. 获取参数并进行签名验证
        2. 校验订单是否有效
        3. 保存支付结果信息并修改订单状态
        4. 返回应答
        """
        # 1. 获取参数并进行签名验证
        data = request.query_params.dict()  # QueryDict->dict

        signature = data.pop('sign')

        # 验证签名
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,  # 应用APPID
            app_notify_url=None,  # 默认回调url
            app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem"),
            # 网站私钥文件路径
            alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                "keys/alipay_public_key.pem"),  # 支付宝公钥文件路径
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 是否使用沙箱环境
        )

        success = alipay.verify(data, signature)

        if not success:
            # 签名验证失败
            return Response({'message': '非法请求'}, status=status.HTTP_403_FORBIDDEN)

        # 2. 校验订单是否有效
        order_id = data.get('out_trade_no')
        try:
            order = OrderInfo.objects.get(
                order_id=order_id,
                user=request.user,
                pay_method=OrderInfo.PAY_METHODS_ENUM['ALIPAY'],
                status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']
            )
        except OrderInfo.DoesNotExist:
            return Response({'message': '无效的订单id'}, status=status.HTTP_400_BAD_REQUEST)

        # 3. 保存支付结果信息并修改订单状态
        trade_id = data.get('trade_no')

        Payment.objects.create(
            order=order,
            trade_id=trade_id
        )

        # 修改订单状态
        order.status = OrderInfo.ORDER_STATUS_ENUM['UNSEND']  # 待发货
        order.save()

        # 4. 返回应答
        return Response({'trade_id': trade_id})
